package com.moli.iov.handle.alarm.enums;

import java.util.Arrays;

/**
 * <p>
 *   Alarm code collection enum.
 *   It's contains
 *   <ul>
 *   <li>Vehicle monitoring alarm.</li>
 *   <li>Fence alarm.</li>
 *   <li>Mileage variation alarm.</li>
 *   <li>Loss of association alarm.</li>
 *   <li>Equipment change alarm.</li>
 *   </ul>
 *   and other properties.
 * </p>
 *
 * @author OAK
 * @version 3.0
 * @since 2019/10/23 15:17:00 PM.
 */
public enum AlarmCodeCollectionEnum {

    /**
     * Vehicle monitoring alarm.
     */
    VEHICLE_MONITORING(0, "车载监控报警", new AlarmLevelEnum[]{
            AlarmLevelEnum.ONE,
            AlarmLevelEnum.PLATFORM,
            AlarmLevelEnum.THREE
        }, new AlarmCodeEnum[]{
            AlarmCodeEnum.TEMPERATURE_DIFFERENCE,
            AlarmCodeEnum.BATTERY_HIGH_TEMPERATURE,
            AlarmCodeEnum.ENERGY_STORING_DEVICE_OVERPRESSURE,
            AlarmCodeEnum.ENERGY_STORING_DEVICE_UNDERPRESSURE,
            AlarmCodeEnum.SOC_LOW,
            AlarmCodeEnum.SINGLE_BATTERY_OVERPRESSURE,
            AlarmCodeEnum.SINGLE_BATTERY_UNDERPRESSURE,
            AlarmCodeEnum.SOC_OVER,
            AlarmCodeEnum.SOC_LEAPING,
            AlarmCodeEnum.STORAGE_SYSTEMS_NON_MATCHED,
            AlarmCodeEnum.BATTERY_SINGLE_CONFORMING_BAD,
            AlarmCodeEnum.INSULATION,
            AlarmCodeEnum.DCDC_TEMPERATURE,
            AlarmCodeEnum.BRAKE_SYSTEM,
            AlarmCodeEnum.DCDC_STATE,
            AlarmCodeEnum.DRIVE_MOTOR_CONTROL_TEMPERATURE,
            AlarmCodeEnum.HIGH_PRESSURE_INTERLOCK_STATE,
            AlarmCodeEnum.DRIVE_MOTOR_TEMPERATURE,
            AlarmCodeEnum.ENERGY_STORING_DEVICE_OVERCHARGE,
            AlarmCodeEnum.STORING_DEVICE,
            AlarmCodeEnum.DRIVE_MOTOR,
            AlarmCodeEnum.BATTERY_VOLTAGE,
            AlarmCodeEnum.SOC
    }),

    /**
     * Fence alarm.
     */
    FENCE(1, "围栏报警", new AlarmLevelEnum[]{
            AlarmLevelEnum.PLATFORM
    }, new AlarmCodeEnum[]{
            AlarmCodeEnum.OUT_FENCE,
            AlarmCodeEnum.IN_FENCE
    }),

    /**
     * Mileage variation alarm.
     */
    MILEAGE_VARIATION(2, "里程异变报警", new AlarmLevelEnum[]{
            AlarmLevelEnum.THREE
    }, new AlarmCodeEnum[]{
            AlarmCodeEnum.MILEAGE_EXCEPTION_CHANGE
    }),

    /**
     * Loss of association alarm.
     */
    LOSS_OF_ASSOCIATION(3,"失联报警", new AlarmLevelEnum[]{
            AlarmLevelEnum.THREE
    }, new AlarmCodeEnum[]{
            AlarmCodeEnum.OFF_LINE
    }),

    /**
     * Equipment change alarm.
     */
    EQUIPMENT_CHANGE(4, "设备变更报警", new AlarmLevelEnum[]{
            AlarmLevelEnum.THREE
    }, new AlarmCodeEnum[]{
            AlarmCodeEnum.DEVICE_CHAGNGE,
            AlarmCodeEnum.DEVICE_TEAR_DOWN,
            AlarmCodeEnum.UNAUTHORIZED_VEHICLE_REGISTRATION
    });

    /**
     * Alarm code collection's code value.
     */
    private int flag;

    /**
     * Alarm code collection's message text.
     */
    private String msg;

    /**
     * Alarm code collection's alarm level collection.
     */
    private AlarmLevelEnum [] levels;

    /**
     * Alarm code collection's children collection.
     */
    private AlarmCodeEnum [] alarmCodeEnums;

    /**
     * Construction a alarm code collection.
     * @param flag Alarm code collection's code value.
     * @param msg Alarm code collection's message text.
     * @param levels Alarm code collection's alarm level collection.
     * @param alarmCodeEnums Alarm code collection's children collection.
     */
    AlarmCodeCollectionEnum(int flag, String msg, AlarmLevelEnum [] levels, AlarmCodeEnum [] alarmCodeEnums){
        this.flag = flag;
        this.msg = msg;
        this.levels = levels;
        this.alarmCodeEnums = alarmCodeEnums;
    }

    /**
     * According to alarm code collection's code value to get a alarm code collection's message text.
     * @param flag Alarm code collection's code value.
     * @return Alarm code collection's message text.
     */
    public static String getMsg(int flag){
        return Arrays.stream(AlarmCodeCollectionEnum.values()).filter(alarmCodeCollectionEnum ->
                alarmCodeCollectionEnum.getFlag() == flag).findFirst().orElse(null).getMsg();
    }

    /**
     * According to alarm code collection's code value to get a alarm code collection.
     * @param flag Alarm code collection's code value.
     * @return Alarm code collection
     */
    public static AlarmCodeCollectionEnum getEnum(int flag){
        return Arrays.stream(AlarmCodeCollectionEnum.values()).filter(alarmCodeCollectionEnum ->
                alarmCodeCollectionEnum.getFlag() == flag).findFirst().orElse(null);
    }

    /**
     * According to alarm code collection's children collection code value to get a alarm code collection.
     * @param childrenFlag Alarm code collection's children collection code value.
     * @return Alarm code collection
     */
    public static AlarmCodeCollectionEnum getAlarmCodeCollectionByChildrenFlag(int childrenFlag){
        return Arrays.stream(AlarmCodeCollectionEnum.values()).filter(alarmCodeCollectionEnum ->
                Arrays.stream(alarmCodeCollectionEnum.getAlarmCodeEnums()).anyMatch(alarmCodeEnum ->
                        alarmCodeEnum.getFlag() == childrenFlag)).findFirst().orElse(null);
    }

    /**
     * Get a alarm code collection's code value.
     * @return Alarm code collection's code value.
     */
    public int getFlag() {
        return flag;
    }

    /**
     * Get a alarm code collection's message text.
     * @return Alarm code collection's message text.
     */
    public String getMsg() {
        return msg;
    }

    /**
     * Get a alarm code collection's alarm level collection.
     * @return Alarm code collection's alarm level collection.
     */
    public AlarmLevelEnum [] getLevels() {
        return levels;
    }

    /**
     * Get a alarm code collection's children collection.
     * @return Alarm code collection's children collection.
     */
    public AlarmCodeEnum [] getAlarmCodeEnums(){
        return alarmCodeEnums;
    }
}
